<!--无痕验证-->
<template>
  <div>
    <div id="captcha"></div>
    <md-input-item ref="id" title="图形验证码" v-model="graphCode" placeholder="请输入图形验证码" v-if="graphCodeStatus" clearable is-title-latent>
      <div class="input-operator" slot="right">
        <img :src="graphImg" class="graphImg" @click="initLoginGraph()">
      </div>
    </md-input-item>
  </div>
</template>
<script>
  import {InputItem, Toast} from 'mand-mobile'
  export default {
    name:'notrace-check',
    components:{
      [InputItem.name]: InputItem,
      [Toast.name]: Toast
    },
    props: {
      scene: { // 使用场景标识
        type: String,
        default() {
          return ''
        }
      },
      systemType: { // 系统类型
        type: String,
        default() {
          return ''
        }
      },
      businessType: { // 业务类型
        type: String,
        default() {
          return ''
        }
      },
      bizValue: { // 业务主键值,如：手机号
        type: String,
        default() {
          return ''
        }
      },
      bizData: { // 备注，格式为JSON
        type: String,
        default() {
          return ''
        }
      },
      width: { // 滑动条的宽度。
        type: Number,
        default() {
          return 300
        }
      },
      fontSize: { // 滑动组件展示的字体大小
        type: Number,
        default() {
          return 12
        }
      },
    },
    data() {
      return {
        jsObj: {
          guide: 'https://g.alicdn.com/AWSC/AWSC/awsc.js'
        },
        graphCode: '',
        graphId: '', 
        graphImg: '',
        graphCodeStatus: false,
        status: null,
        successStatus: false,
        checkType: '', // 验证类型
        verifyData: '', // 二次验证是
        ssId: '' // 风险控制Id
      }
    },
    async mounted() {
      //新版app交互js
      await this.initJs(this.jsObj.guide)
      this.aliInit()
    },
    methods: {
      // 引入文件
      async initJs(jsUrl) {
        return await new Promise((resolve) => {
          let script = document.createElement('script')
          let header = document.getElementsByTagName('head')[0]
          script.type = 'text/javascript'
          script.src = jsUrl
          header.appendChild(script)
          script.onload = script.onreadystatechange = function () {
            if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') {
              resolve(true)
            }
            script.onload.onload = script.onreadystatechange = null //删除事件处理函数。
          }
        })
      },
      // 初始化
      aliInit() {
        let _this = this
        AWSC.use("nvc", function (state, module) {
          // 初始化 调用module.init进行初始化
          window.nvc = module.init({
              // 应用类型标识。它和使用场景标识（scene字段）一起决定了无痕验证的业务场景与后端对应使用的策略模型。您可以在人机验证控制台的配置管理页签找到对应的appkey字段值，请务必正确填写。
              appkey: process.env.VUE_APP_NC_KEY,
              //使用场景标识。它和应用类型标识（appkey字段）一起决定了无痕验证的业务场景与后端对应使用的策略模型。您可以在人机验证控制台的配置管理页签找到对应的scene值，请务必正确填写。
              scene: _this.scene,
              test: module.TEST_NC_PASS,
              // 二次验证获取人机信息串，跟随业务请求一起上传至业务服务器，由业务服务器进行验签。
              success: function (data) {
                console.log(data)
                _this.verifyData = data
                _this.init()
              },
              // 前端二次验证失败时触发该回调参数
              fail: function (failCode) {
                console.log(failCode)
              },
              // 前端二次验证加载异常时触发该回调参数。
              error: function (errorCode) {
                console.log(errorCode)
              }
          })
        })
      },
      // 初始化接口
      init() {
        let _this = this
        _this.$nextTick(() => {
          if(!_this.status) {
            if((_this.checkType == 'GRAPH_CODE_VERIFY' || _this.checkType == 'TRACELESS_GRAPH_VERIFY') && _this.graphCode) {
              _this.validate(_this.graphCode)
              return
            }
            if((_this.checkType == 'TRACELESS_VERIFY_NC') && _this.verifyData) {
              _this.validate(_this.verifyData)
              return
            }
            if(_this.checkType == 'TRACELESS_VERIFY_NC') {
              Toast.info('请按住滑块，拖动到最右边')
              return
            }
            _this.safetyQuery()
          } else {
            window.nvc.reset()
            _this.safetyQuery()
          }
        })
      },
      // 安全性查询接口
      safetyQuery() {
        let _this = this
        console.log(window.nvc.getNVCVal())
        var params = window.nvc.getNVCVal() // 获取阿里人机信息串
        let data = {
          systemType: _this.systemType, // 系统类型
          businessType: _this.businessType, // 业务类型
          queryData: params, // 获取阿里人机信息串
          bizValue: _this.bizValue, // 业务主键值,如：手机号
          bizData: _this.bizData // 备注，格式为JSON
        }
        _this.ajax({
          url: `${process.env.VUE_APP_BASIS_URL}/safety/query`,
          type:'post',
          data:JSON.stringify(data),
          dataType:'json',
          timeout:10000,
          success:function(res) {
            console.log(res)
            if(res.resultCode == '1') {
              _this.ssId = res.ssId
              switch(res.code) {
                case '0': // 未通过
                  _this.status = false
                  _this.$emit('callBack',{status: _this.status,ssId: res.ssId})
                break
                case '1': // 通过
                  _this.status = true
                  _this.$emit('callBack',{status: _this.status,ssId: res.ssId})
                break
                case '2': // 待验证
                  switch(res.checkType) {
                    case 'TRACELESS_VERIFY_NC':
                      //唤醒滑动验证
                      var ncoption = {
                        // 声明滑动验证需要渲染的目标ID。
                        renderTo: "#captcha",
                        // 滑动条的宽度。
                        width: _this.width,
                        // 滑块字体大小
                        fontSize: _this.fontSize
                      } 
                      // 唤醒二次验证（滑动验证码）
                      if(!_this.successStatus) {
                        window.nvc.getNC(ncoption)
                      } else {
                        // console.log('重置')
                        _this.status = false
                        _this.verifyData = ''
                        window.nvc.reset()
                      }
                      _this.successStatus = true
                    break
                    case 'GRAPH_CODE_VERIFY':
                    case 'TRACELESS_GRAPH_VERIFY':
                      _this.graphId = res.verifyData
                      // 图形验证码
                      _this.status = false
                      _this.graphCodeStatus = true
                      _this.graphImg = `${process.env.VUE_APP_BASIS_URL}/safety/showGraph/${res.verifyData}`
                    break
                  }
                  _this.checkType = res.checkType
                break
              }
              _this.$emit('callBack',{status: _this.status,ssId: res.ssId})
            } else {
              Toast.info(res.resultMessage || '系统异常，请稍后在试')
            }
          },
          error:function(e){
            console.log(e);
          }
        })
      },
      // 安全性验证接口
      validate(verifyData) {
        let _this = this
        let data = {
          systemType: _this.systemType, // 系统类型
          businessType: _this.businessType, // 业务类型
          verifyData: verifyData, // 阿里验证为人机信息串，图形验证码为输入参数
          graphId: _this.graphId, // 图形验证码Id
          ssId: _this.ssId // 风控Id
        }
        _this.ajax({
          url: `${process.env.VUE_APP_BASIS_URL}/safety/validate`,
          type:'post',
          data:JSON.stringify(data),
          dataType:'json',
          timeout:10000,
          success:function(res) {
            if(res.resultCode == '1') {
              if(res.code == '1') {
                _this.status = true
                _this.$emit('callBack',{status: _this.status,ssId: _this.ssId})
              } else if(res.code == '0') {
                _this.status = false
                _this.$emit('callBack',{status: _this.status,ssId: _this.ssId})
              }
            } else {
              Toast.info(res.resultMessage || '系统异常，请稍后在试')
            }
          },
          error:function(e) {
            console.log(e)
          }
        })
      },
      // 重新获取图形验证码
      initLoginGraph() {
        this.safetyQuery()
      },
      // 封装ajax请求
      ajax(options) {
        options = options || {};  //调用函数时如果options没有指定，就给它赋值{},一个空的Object
        options.type=(options.type || "GET").toUpperCase();/// 请求格式GET、POST，默认为GET
        options.dataType=options.dataType || "json";    //响应数据格式，默认json

        var params=options.data
        var xhr;
        //考虑兼容性
        if(window.XMLHttpRequest) {
          xhr=new XMLHttpRequest();
        } else if(window.ActiveObject) {//兼容IE6以下版本
          xhr=new ActiveXobject('Microsoft.XMLHTTP');
        }
        //启动并发送一个请求
        if(options.type=="GET") {
          xhr.open("GET",options.url+"?"+params,true);
          xhr.send(null);
        }else if(options.type=="POST"){
          xhr.open("post",options.url,true);
          //设置表单提交时的内容类型
          //Content-type数据请求的格式
          xhr.setRequestHeader("Content-type","application/json;charset=UTF-8");
          xhr.send(params);
        }

        // 设置有效时间
        setTimeout(function() {
          if(xhr.readySate!=4){
            xhr.abort();
          }
        },options.timeout)
        // 接收
        // options.success成功之后的回调函数  options.error失败后的回调函数    //xhr.responseText,xhr.responseXML  获得字符串形式的响应数据或者XML形式的响应数据
        xhr.onreadystatechange=function(){
          if(xhr.readyState == 4){
            var status=xhr.status;
            if(status >= 200 && status < 300 || status == 304 || status == 404){
              options.success&&options.success(JSON.parse(xhr.responseText),xhr.responseXML);
            } else {
              options.error&&options.error(status);
            }
          }
        }
      },
      // 过滤空值
      eliminate (obj = {}) {
        let params = { ...obj }
        let reParams = {}
        for (let key in params) {
          if (params.hasOwnProperty(key)) {
            if ((!params[key] || params[key] == '') && params[key] != '0') {
              //
            } else {
              reParams[key] = params[key]
            }
          }
        }
        return reParams
      }
    }
  }
</script>

<style lang="less" scoped>
  /deep/.nc-prepared {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 20px;
  }
  /deep/.sm-pop-inner {
    width: auto;
  }
  /deep/.nc-container {
    box-sizing: border-box;
    margin: 20px 0;
  }
  /deep/.md-input-item {
    .graphImg {
      width: 180px;
      height: 80px;
    }
  }
</style>